package team.nmsg.ge.system.init.shiro;
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.Filter;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
/**
 * Shiro 配置
 *
 * Apache Shiro 核心通过 Filter 来实现，就好像SpringMvc 通过DispachServlet 来主控制一样。 既然是使用
 * Filter 一般也就能猜到，是通过URL规则来进行过滤和权限校验，所以我们需要定义一系列关于URL的规则和访问权限。
 *
 */
@Configuration
public class ShiroConfiguration {
      
	@Bean
	public SysShiroSessionListener sessionListener(){
		SysShiroSessionListener sessionListener = new SysShiroSessionListener();
		return sessionListener;
	}
	
	@Bean
	public MemorySessionDAO sessionDao(){
		MemorySessionDAO sessionDao = new MemorySessionDAO();
		return sessionDao;
	}
	
	@Bean
	public ShiroSessionManager sessionManager
		(MemorySessionDAO sessionDao , SysShiroSessionListener sessionListener){
		ShiroSessionManager sessionManager = new ShiroSessionManager();
		sessionManager.setSessionDAO(sessionDao);
		List<SessionListener> ls = new ArrayList<SessionListener>();
		ls.add(sessionListener);
		sessionManager.setSessionListeners(ls);
		return sessionManager;
	}
	
	@Bean
	public SysAuthorizingRealm nmsRealm() {
		SysAuthorizingRealm nmsRealm = new SysAuthorizingRealm();
		return nmsRealm;
	}

	
	/**
	 * shiro缓存管理器; 需要注入对应的其它的实体类中： 1、安全管理器：securityManager
	 * 可见securityManager是整个shiro的核心；
	 * 
	 * @return
	 */
	@Bean
    public EhCacheManager ehCacheManager(){
       EhCacheManager cacheManager = new EhCacheManager();
       cacheManager.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");
       return cacheManager;
    }

    
	@Bean
	public SecurityManager securityManager( SysAuthorizingRealm nmsRealm , DefaultWebSessionManager sessionManager ) {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		// 设置realm.
		securityManager.setRealm( nmsRealm );
		securityManager.setSessionManager(sessionManager);
		securityManager.setCacheManager(ehCacheManager());
		return securityManager;
	}
	
   
 
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){
    	ShiroFilterFactoryBean shiroFilter  = new ShiroFilterFactoryBean();
      
        // 必须设置 SecurityManager 
    	shiroFilter.setSecurityManager(securityManager);
    	shiroFilter.setLoginUrl("/login");
    	shiroFilter.setUnauthorizedUrl("/noAuth");
    	
    	Map<String, Filter> filters = new HashMap<String, Filter>();
    	SysFormAuthenticationFilter nmsFormFilter = new SysFormAuthenticationFilter();
    	filters.put("authc", nmsFormFilter);
    	shiroFilter.setFilters(filters);
    	
       Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
       filterChainDefinitionMap.put("/", "anon");
       filterChainDefinitionMap.put("/login", "anon");
       filterChainDefinitionMap.put("/login2", "anon");
       filterChainDefinitionMap.put("/files/**", "anon");
       filterChainDefinitionMap.put("/resources/**", "anon");
       filterChainDefinitionMap.put("/logOut", "anon");
       filterChainDefinitionMap.put("/language", "anon");
       filterChainDefinitionMap.put("/noAuth", "anon");
       filterChainDefinitionMap.put("/changePassword", "anon");
       filterChainDefinitionMap.put("/relogin", "anon");
       filterChainDefinitionMap.put("/t/*", "anon");
//       filterChainDefinitionMap.put("/tconnect", "anon");
       filterChainDefinitionMap.put("/**", "authc");
       
       shiroFilter.setFilterChainDefinitionMap(filterChainDefinitionMap);
       
       return shiroFilter;
    }
   
   

	@Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }
	
	@Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator creator=new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }
	
	@Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(  DefaultWebSecurityManager manager) {
        AuthorizationAttributeSourceAdvisor advisor=new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(manager);
        return advisor;
    }
   
}
